#pragma once

#include <functional>
#include <cstdio>

int Compute(int x, int y, char op)
{
    switch(op)
    {
    case '+':
        return x + y;
    case '-':
        return x - y;
    case '*':
        return x * y;
    case '/':
    {
        if (y == 0)
        {
            cerr << "div zero error" << endl;
            return -1;
        }
        return x / y;
    }
    case '%':
    {
        if (y == 0)
        {
            cerr << "div zero error" << endl;
            return -1;
        }
        return x % y;
    }
    }
}

void Save(const string& str)
{
    FILE* fp = fopen("log.txt", "a+");
    if (fp == nullptr)
    {
        cerr << "file open failed" << endl;
        return;
    }
    fprintf(fp, "%s\n", str.c_str());
    fclose(fp);
}

class c_task
{
public:
    typedef function<int(int, int, char)> func;

    c_task()
    {}

    c_task(int x, int y, char op, func f)
    : _x(x),
      _y(y),
      _op(op),
      _f(f)
    {}

    string operator()()
    {
        int result = _f(_x, _y, _op);
        char buffer[64];
        snprintf(buffer, sizeof buffer, "%d %c %d = %d", _x, _op, _y, result);
        return buffer;
    }

    string toTaskString()
    {
        char buffer[64];
        snprintf(buffer, sizeof buffer, "%d %c %d = ?", _x, _op, _y);
        return buffer;
    }
private:
    int _x;
    int _y;
    char _op;
    func _f;
};

class s_task
{
public:
    typedef function<void(const string&)> func;

    s_task()
    {}

    s_task(const string& ret, func f)
    : _ret(ret),
      _f(f)
    {}

    void operator()()
    {
        _f(_ret);
    }

private:
    string _ret;
    func _f;
};